import { systemTaskInfoQuery } from '@/api/task'
import { message, notification, Typography } from 'antd'
import dayjs from 'dayjs'
import { saveAs } from 'file-saver'
import { NavigateFunction } from 'react-router-dom'

export const getRecentThreeMonths = () => {
  const endDate = dayjs().endOf('day')
  const startDate = dayjs().subtract(6, 'month').startOf('day')
  return [startDate, endDate]
}
export const getRecentMonths = (customFormat?: string) => {
  const endDate = dayjs()
    .endOf('day')
    .format(customFormat ? customFormat : 'YYYY-MM-DD HH:mm:ss')
  const startDate = dayjs()
    .subtract(6, 'month')
    .startOf('day')
    .format(customFormat ? customFormat : 'YYYY-MM-DD HH:mm:ss')
  return [startDate, endDate]
}
export const getRecentSixMonths = () => {
  const endDate = dayjs().endOf('day')
  const startDate = dayjs().subtract(6, 'month').startOf('day')
  return [startDate, endDate]
}
export const getRecentSeventDays = (customFormat?: string) => {
  const endDate = dayjs()
    .endOf('day')
    .format(customFormat ? customFormat : 'YYYY-MM-DD HH:mm:ss')
  const startDate = dayjs()
    .subtract(7, 'day')
    .startOf('day')
    .format(customFormat ? customFormat : 'YYYY-MM-DD HH:mm:ss')
  return [startDate, endDate]
}
export const downloadByOwnUrl = (url: string) => {
  const start = url.lastIndexOf('/') + 1
  const fileurl = url.slice(start)
  const dotArr = fileurl?.split('.')
  const name = dotArr[0]?.split('_')?.[0]
  if (start >= 0 && name) {
    const extension = dotArr[dotArr.length - 1]
    const fileurlname = name + '.' + extension
    fetch(url)
      .then((response) => response.blob())
      .then((blob) => saveAs(blob, fileurlname))
      .catch((error) => console.error(error))
  } else {
    const dot = url.split('.').pop()
    const tempName = dayjs().valueOf()
    fetch(url)
      .then((response) => response.blob())
      .then((blob) => saveAs(blob, tempName + '.' + dot))
      .catch((error) => console.error(error))
  }
}
export const getNameByOwnUrl = (url: string) => {
  const start = url.lastIndexOf('/') + 1
  const fileurl = url.slice(start)
  const dotArr = fileurl?.split('.')
  const name = dotArr[0]?.split('_')?.[0]
  if (start >= 0 && name) {
    const extension = dotArr[dotArr.length - 1]
    const fileurlname = name + '.' + extension
    return fileurlname
  } else {
    return url
  }
}

export const downloadByUrl = (url: string, filename?: string) => {
  const start = url.lastIndexOf('/') + 1
  const fileurl = url.slice(start)
  const dotArr = fileurl?.split('.')
  const name = dotArr[0]?.split('_')?.[0]
  if (start >= 0 && name) {
    const extension = dotArr[dotArr.length - 1]
    const fileurlname = name + '.' + extension
    fetch(url)
      .then((response) => response.blob())
      .then((blob) => saveAs(blob, fileurlname))
      .catch((error) => console.error(error))
  } else {
    const dot = url.split('.').pop()
    const tempName = dayjs().valueOf()
    fetch(url)
      .then((response) => response.blob())
      .then((blob) => saveAs(blob, (filename ? filename : tempName) + '.' + dot))
      .catch((error) => console.error(error))
  }
}
export const downloadByUrlBigFile = (url: string, filename?: string) => {
  const link = document.createElement('a')
  link.href = url
  link.download = filename || ''
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
  URL.revokeObjectURL(url)
}
export const checkIsReply = (uuid: string, MAX = 2, timer = 4000): Promise<string | false> => {
  let current = 0 // 当前次数
  return new Promise((resolve) => {
    const check = async () => {
      current++
      const res = await systemTaskInfoQuery<{ fileId: string }>({ uuid })
      if (res?.data?.list && res?.data?.list?.length > 0 && res?.data?.list?.[0]?.fileId) {
        resolve(res?.data?.list?.[0]?.fileId)
        current = 0
      } else if (current <= MAX) {
        setTimeout(check, timer)
      } else {
        resolve(false)
      }
    }
    check()
  })
}

export const exportNotification = async (uuid: string, navigate: NavigateFunction, path = '/task/center/list') => {
  const hasReplyUrl = await checkIsReply(uuid)
  if (hasReplyUrl) {
    const filename = getNameByOwnUrl(hasReplyUrl)
    downloadByUrlBigFile(hasReplyUrl, filename)
    message.success('导出成功')
  } else {
    const key = `open${Date.now()}`
    notification.warning({
      message: (
        <div style={{ userSelect: 'none' }}>
          <div style={{ fontWeight: 500, fontSize: 20 }}>本次导出数据量较大！</div>
          <div>任务执行中，请稍后前往任务中心查看</div>
        </div>
      ),
      description: (
        <Typography.Link
          onClick={() => {
            navigate(path)
            notification.destroy(key)
          }}
          style={{ userSelect: 'none' }}
        >
          点击跳转任务中心
        </Typography.Link>
      ),
      duration: null,
      key,
    })
  }
}

export const importNotification = async (linkUrl: string) => {
  if (linkUrl) {
    const key = `open${Date.now()}`
    notification.open({
      type: 'warning',
      message: <div style={{ fontWeight: 500, userSelect: 'none' }}>存在导入失败的数据</div>,
      description: (
        <Typography.Paragraph>
          <Typography.Link
            onClick={() => {
              downloadByUrl(linkUrl, '批量导入失败详情')
              notification.destroy(key)
            }}
            style={{ marginRight: 4, userSelect: 'none' }}
          >
            点击下载
          </Typography.Link>
          <Typography.Text>获取失败原因</Typography.Text>
        </Typography.Paragraph>
      ),
      duration: null,
      key,
    })
  } else {
    notification.open({
      type: 'success',
      message: '所有数据导入成功',
      duration: 5,
    })
  }
}

export const importNotificationByFirstErrorMsg = async (linkUrl: string, firstErrorMsg: string) => {
  if (linkUrl) {
    const key = `open${Date.now()}`
    notification.open({
      type: 'warning',
      message: <div style={{ fontWeight: 500, userSelect: 'none' }}>存在导入失败的数据</div>,
      description: (
        <Typography.Paragraph>
          <Typography.Paragraph>第一条失败原因：{firstErrorMsg}</Typography.Paragraph>
          <Typography.Link
            onClick={() => {
              downloadByUrl(linkUrl, '批量导入失败详情')
              notification.destroy(key)
            }}
            style={{ marginRight: 4, userSelect: 'none' }}
          >
            点击下载
          </Typography.Link>
          <Typography.Text>获取完整失败原因</Typography.Text>
        </Typography.Paragraph>
      ),
      duration: null,
      key,
    })
  } else {
    notification.open({
      type: 'success',
      message: '所有数据导入成功',
      duration: 5,
    })
  }
}

export const importNotificationSpec = async (uuid: string, navigate: NavigateFunction, path = '/task/center/list') => {
  const hasReplyUrl = await checkIsReply(uuid)
  if (hasReplyUrl) {
    const filename = getNameByOwnUrl(hasReplyUrl)
    downloadByUrlBigFile(hasReplyUrl, filename)
    message.success('导入成功')
  } else {
    const key = `open${Date.now()}`
    notification.warning({
      message: (
        <div style={{ userSelect: 'none' }}>
          <div style={{ fontWeight: 500, fontSize: 20 }}>本次导入数据量较大！</div>
          <div>任务执行中，请稍后前往任务中心查看</div>
        </div>
      ),
      description: (
        <Typography.Link
          onClick={() => {
            navigate(path)
            notification.destroy(key)
          }}
          style={{ userSelect: 'none' }}
        >
          点击跳转任务中心
        </Typography.Link>
      ),
      duration: null,
      key,
    })
  }
}

interface TreeNode {
  id: number | string
  productDataType: string
  children?: any[]
  cupType?: string | number
}
export const findDataTypeAndCollectIds = (tree: any[], predicate: (node: TreeNode) => boolean): (string | number)[] => {
  const resultIds: (string | number)[] = []
  function recursiveSearch(node: TreeNode, path: (string | number)[] = [], found = false) {
    const currentPath = [...path, node.id]
    if (predicate(node)) {
      resultIds.push(...currentPath)
      found = true
    }
    if (!found && node.children) {
      for (const child of node.children) {
        recursiveSearch(child, currentPath, found)
      }
    }
  }
  for (const rootNode of tree) {
    recursiveSearch(rootNode)
  }
  return resultIds
}

export const handleDetailFactory = (
  sourceList: IDesListType,
  targetInfo: any,
  set: React.Dispatch<React.SetStateAction<IDesListType>>,
) => {
  const res = sourceList
    ?.filter((item) => !item?.hidden)
    ?.map((item) => {
      if (typeof item.format === 'function') {
        return {
          ...item,
          content: item.format(targetInfo),
        }
      } else {
        return {
          ...item,
          content: targetInfo[item.key + ''] || '-',
        }
      }
    })
  set(res)
}
export const handleDetailFactoryHasNode = (
  sourceList: IDesListType,
  targetInfo: any,
  set: React.Dispatch<React.SetStateAction<IDesListType>>,
) => {
  const res = sourceList
    ?.filter((item) => !item?.hidden)
    ?.map((item: any) => {
      if (typeof item.content !== 'string' && item.formContent != undefined && item.isShowForm != undefined) {
        return {
          ...item,
        }
      } else if (typeof item.format === 'function') {
        return {
          ...item,
          content: item.format(targetInfo),
        }
      } else {
        return {
          ...item,
          content: targetInfo[item.key + ''] || '-',
        }
      }
    })
  set(res)
}
export function formatNumber(numStr: string | number | null | undefined) {
  if (numStr == null || numStr == undefined) return '-'
  // 使用正则表达式匹配整数部分并添加千分位分隔符
  return numStr.toString().replace(/^(\d+)(\.\d+)?$/, function (match, p1, p2) {
    return p1.replace(/\B(?=(\d{3})+(?!\d))/g, ',') + (p2 || '')
  })
}

export function handleTemplateStr(key: string, obj: Record<string, any>) {
  if (obj?.required?.includes(key)) {
    return '必填'
  } else if (obj?.notRequired?.includes(key)) {
    return '非必填'
  } else if (obj?.notShow?.includes(key)) {
    return '不显示'
  } else {
    return '-'
  }
}

export function getDateIsLate(planTime: string | undefined | null, actualTime: string | undefined | null): boolean {
  if (planTime == null && actualTime == null) {
    return false
  }
  const plan = dayjs(planTime)
  const actual = dayjs(actualTime)
  if (planTime != null && actualTime == null) {
    return dayjs().isAfter(plan)
  }
  return actual.isAfter(plan)
}

export function compareObjectsByKey(
  obj1: Record<string, any> | undefined,
  obj2: Record<string, any> | undefined,
  originObj: Record<string, any> | null,
  key: string,
) {
  if (originObj && Object.keys(originObj).length === 0) return true
  if (obj1 && obj2 === undefined) return false
  if (obj1 === undefined || obj2 === undefined) return true
  return obj1[key] === obj2[key]
}

export function debounce(fn: any, delay: number) {
  let timeout: ITimeoutType
  return (...set: any) => {
    if (timeout) clearTimeout(timeout)
    timeout = setTimeout(() => {
      fn(...set)
    }, delay)
  }
}
